import { Button, Modal } from 'antd';
import { get, set, each } from 'lodash';
import { toJS, observable, action } from 'mobx';
import * as React from 'react';
import getBorderedColRanges, { getNextColBorderedRanges } from '../../utils/getBorderedColRanges';
import getPinyin from "../../utils/getPy";
import utils from '../../utils';
import AddSelectOptionsStore from '../dialog/addSelectOptionsStore';
import CellType from './celltypes';
import API from '../../apis/excel';
import * as CommonAction from './action/common';
import {WeaLocaleProvider} from "ecCom";
const getLabel = WeaLocaleProvider.getLabel;

export default class QuickTableStore {
    @observable loading = false;
    @observable workbook;
    @observable title;
    @observable addSelectOptionsStore;
    @observable excelStore;
    constructor(excelStore) {
        this.excelStore = excelStore;
        this.addSelectOptionsStore = new AddSelectOptionsStore();
        each({ ...CommonAction }, (value, key) => {
            if (typeof value === 'function') {
                this[key] = action(value.bind(this));
            } else {
                this[key] = value;
            }
        });
    }
    initWorkbook = (file) => {
        this.loading = true;
        if (this.workbook) {
            window.workbookInstance = this.workbook;
            const excelIO = new GC.Spread.Excel.IO();
            excelIO.open(file, (json) => {
                this.title = file.name.replace('.xlsx', '');
                this.workbook.fromJSON(json, false);
                this.workbook.suspendPaint();
                this.workbook.sheets.forEach(sheet => {
                    sheet.tables.all().forEach((table, index) => {
                        table.name(`tempTable${index}`);
                    });
                });
                this.workbook.resumePaint();
                this.initJSON = this.workbook.toJSON();
            }, (e) => {
                if(!!(window.console&&window.console.log)) {
                    window.console.log(e);
                }
                return;
            });
            this.loading = false;
        } else {
            setTimeout(() => { this.initWorkbook(file) }, 50);
        }
    }
    @action
    save = () => {
        this.loading = true;
        API.saveFormAndField({
            appid: this.excelStore.appid,
            json: JSON.stringify(this.workbook.toJSON(false)),
            title: this.title,
        }).then(this.showPage);
    }
    @action
    showPage = (page) => {
        this.loading = false;
        this.excelStore.quickTableVisible = false;
        this.excelStore.showPage(page);
        this.excelStore.reloadHeadTabs(page);
    }
    setFieldType = (fieldType) => {
        const sheet = this.workbook.getActiveSheet();
        sheet.suspendPaint();
        const selections = sheet.getSelections();
        const fieldKeys = [];
        const QuickTableFieldCellType = CellType('QuickTableFieldCellType');
        selections.forEach(selection => {
            const { row, col, rowCount, colCount } = selection;
            for (let rowIndex = 0; rowIndex < rowCount; rowIndex++) {
                for (let colIndex = 0; colIndex < colCount; colIndex++) {
                    const currentRow = row + rowIndex;
                    const currentCol = col + colIndex;
                    const span = sheet.getSpan(currentRow, currentCol);
                    let currentCell;
                    if (span) {
                        if (span.row !== currentRow || span.col !== currentCol) {
                            continue;
                        }
                        currentCell = sheet.getRange(span.row, span.col, span.rowCount, span.colCount);
                    } else {
                        currentCell = sheet.getCell(currentRow, currentCol);
                    }
                    const currentSingleCell = sheet.getCell(currentCell.row, currentCell.col);
                    let cellType = currentSingleCell.cellType();
                    if (cellType && cellType.typeName === 'QuickTableFieldCellType') {
                        
                        cellType.setFieldType(fieldType);
                        currentCell.backgroundImage(cellType.backgroundImage);
                    } else {
                        const name = sheet.name();
                        let currentMainTable;
                        this.mainTables.forEach(d => {
                            if (d.tableName === name) {
                                currentMainTable = d;
                            }
                        });
                        if (!currentMainTable) {
                            currentMainTable = {
                                detailTables: [],
                                fields: [],
                                tableName: name
                            };
                            this.mainTables.push(currentMainTable);
                        }
                        const sheetIndex = this.workbook.getSheetIndex(name);
                        const mainTable = `mainTable_${sheetIndex}`;
                        const fieldIndex = this.getFieldIndex(mainTable, "mainTable");
                        const label = this.getMainTableFieldName(sheet, currentCell.row, currentCell.col, fieldIndex);
                        const fieldName = this.getFieldName(mainTable, "mainTable", getPinyin(label)[0]);
                        const newFieldIndex = currentMainTable.fields.length;
                        currentMainTable.fields.push({
                            col: currentCell.col,
                            colCount: currentCell.colCount,
                            fieldName,
                            fieldType,
                            label,
                            row: currentCell.row,
                            rowCount: currentCell.rowCount,
                        });
                        cellType = new QuickTableFieldCellType(this, `mainTables[${this.mainTables.indexOf(currentMainTable)}].fields[${newFieldIndex}]`);
                        currentCell.textIndent(2.5)
                            .backgroundImageLayout(GC.Spread.Sheets.ImageLayout.none)
                            .backgroundImage(cellType.backgroundImage);
                        currentSingleCell.cellType(cellType);
                    }

                    fieldKeys.push(cellType.fieldKey);
                }
            }
        });
        sheet.resumePaint();
        const [htmltype] = fieldType;
        if (htmltype === 'select') {
            const save = () => {
                fieldKeys.forEach(key => {
                    set(this, `${key}.fieldType[2].datas`, toJS(this.addSelectOptionsStore.datas));
                });
                this.addSelectOptionsStore.hide();
                this.addSelectOptionsStore.datas = [];
            }
            this.addSelectOptionsStore.fieldType='select';
            this.addSelectOptionsStore.open();
            this.addSelectOptionsStore.initOptions(fieldKeys.length > 1 ? [] : get(this, `${fieldKeys[0]}.fieldType[2].datas`));
            this.addSelectOptionsStore.buttons[1] = (<Button ecId={`${this && this.props && this.props.ecId || ''}_Button@6os9ea`} key="ok" onClick={save} type="primary">{getLabel('30986','保存')}</Button>);
        }
    }
    signFields = () => {
        const QuickTableFieldCellType = CellType('QuickTableFieldCellType');
        const action = () => {
            this.loading = true;
            this.clearFields();
            this.workbook.fromJSON(this.initJSON, false);
            this.workbook.sheets.forEach((sheet, sheetIndex) => {
                const sheetName = sheet.name();
                const mainTableObj = {
                    detailTables: [],
                    fields: [],
                    tableName: `${this.title}${sheetName}`,
                    sheetName
                }

                const mainTable = `mainTable_${sheetIndex}`;
                const maxRowCount = sheet.getRowCount();
                const maxColCount = sheet.getColumnCount();
                sheet.tables.all().sort((a,b) => {
                    const { row: arow, col: acol } = a.dataRange();
                    const { row: brow, col: bcol } = b.dataRange();

                    let diff = arow -brow;
                    if(diff == 0) {
                        diff = acol - bcol;
                    }
                    return diff;
                }).forEach(table => {
                    const { colCount } = table.range();
                    const { row: dataRow, col: dataCol } = table.dataRange();
                    const detailIndex = this.getDetailIndex(mainTable);
                    const detail = `detail_${detailIndex}`;
                    const detailFields = [];
                    table.name(`detail${detailIndex}`);
                    table.bindingPath(`${sheetName}.${detail}`);
                    for (let index = 0; index < colCount; index++) {
                        let label = table.getColumnName(index);
                        const fieldIndex = this.getFieldIndex(mainTable, detail);
                        let fieldName;
                        if (label) {
                            fieldName = getPinyin(label)[0];
                        } else {
                            label = `${getLabel('502711','字段')+fieldIndex}`;
                        }
                        if (!fieldName) {
                            fieldName = `field${fieldIndex}`;
                        }
                        fieldName = this.getFieldName(mainTable, detail, fieldName).toLowerCase();
                        table.setColumnDataField(index, fieldName);

                        detailFields.push({
                            col: dataCol + index,
                            colCount: 1,
                            fieldName,
                            fieldType: ['input', 'text', '200'],
                            label,
                            row: dataRow,
                            rowCount: 1,
                            uuid: utils.UUID(),
                            detailIndex
                        });
                    }

                    mainTableObj.detailTables.push({
                        ...table.range(),
                        detailIndex,
                        fields: detailFields,
                    });
                });

                for (let rowIndex = 0; rowIndex < maxRowCount; rowIndex++) {
                    for (let colIndex = 0; colIndex < maxColCount; colIndex++) {
                        if (sheet.tables.find(rowIndex, colIndex)) {
                            continue;
                        }

                        let currentCell;
                        const span = sheet.getSpan(rowIndex, colIndex);
                        if (span) {
                            if (span.row !== rowIndex || span.col !== colIndex) {
                                continue;
                            }
                            currentCell = sheet.getRange(span.row, span.col, span.rowCount, span.colCount);
                        } else {
                            currentCell = sheet.getCell(rowIndex, colIndex);
                        }
                        const isInDetails = this.isInDetails.bind(this, mainTableObj);
                        let rangeRowCounts = [];
                        let rangeRowCounts1 = getBorderedColRanges(sheet, currentCell, isInDetails);
                        let range1 = currentCell;
                        const rangeColCounts = [];
                        while (rangeRowCounts1.length > 2) {
                            rangeRowCounts = rangeRowCounts1;
                            rangeColCounts.push(range1.colCount)
                            const [rangeRowCountsTemp, rangeTemp] = getNextColBorderedRanges(sheet, range1, rangeRowCounts1, isInDetails);
                            rangeRowCounts1 = rangeRowCountsTemp;
                            range1 = rangeTemp;
                        }
                        if (rangeColCounts.length > 1 && rangeRowCounts.length > 2) {
                            const sum = (...args) => {
                                let rt = 0;
                                args.map(n => {
                                    rt += n;
                                });
                                return rt;
                            }
                            const detailIndex = this.getDetailIndex(mainTable);
                            const tempDetail = `detail_${detailIndex}`;
                            const detailRowCount = sum(...rangeRowCounts);
                            const detailColCount = sum(...rangeColCounts);
                            const detailTable = {
                                col: currentCell.col,
                                colCount: detailColCount,
                                detailIndex,
                                fields: [],
                                row: currentCell.row,
                                rowCount: detailRowCount,
                            };
                            mainTableObj.detailTables.push(detailTable);
                            let tempCol = currentCell.col;
                            const tempRow = currentCell.row + rangeRowCounts[0];
                            const tempStartRow = currentCell.row;
                            rangeColCounts.forEach(tempColCount => {
                                let templabel = sheet.getRange(tempStartRow, tempCol).value();
                                const tempFieldIndex = this.getFieldIndex(mainTable, tempDetail);
                                if (!templabel) {
                                    templabel = `${getLabel('502711','字段')+tempFieldIndex}`;
                                }
                                const tempFieldName = this.getFieldName(mainTable, "mainTable", getPinyin(templabel)[0]);
                                detailTable.fields.push({
                                    col: tempCol,
                                    colCount: tempColCount,
                                    fieldName: tempFieldName,
                                    fieldType: ['input', 'text', '200'],
                                    label: templabel,
                                    row: tempRow,
                                    rowCount: detailRowCount[1],
                                    uuid: utils.UUID(),
                                    detailIndex: detailTable.detailIndex
                                });
                                tempCol += tempColCount;
                            });

                            const table = sheet.tables.add(`detail${detailIndex}`, rowIndex, colIndex, detailRowCount, detailColCount);
                            table.filterButtonVisible(false);
                            table.bindingPath(`${sheetName}.${tempDetail}`);
                            const columns = detailTable.fields.map(field => (
                                new GC.Spread.Sheets.Tables.TableColumn(field.fieldName).name(field.label).dataField(field.fieldName)
                            ));
                            table.bindColumns(columns);
                        }
                        if (isInDetails(rowIndex, colIndex)) {
                            continue;
                        }
                        if (currentCell.value()) {
                            continue;
                        }

                        if (!!currentCell.borderBottom()) {
                            const fieldIndex = this.getFieldIndex(mainTable, "mainTable");
                            const label = this.getMainTableFieldName(sheet, rowIndex, colIndex, fieldIndex);
                            const fieldName = this.getFieldName(mainTable, "mainTable", getPinyin(label)[0]).toLowerCase();
                            currentCell.bindingPath(`${sheetName}.${fieldName}`);
                            mainTableObj.fields.push({
                                col: colIndex,
                                colCount: currentCell.colCount,
                                fieldName,
                                fieldType: ['input', 'text', '200'],
                                label,
                                row: rowIndex,
                                uuid: utils.UUID(),
                                rowCount: currentCell.rowCount,
                            });
                        }
                    }
                }
                if (mainTableObj.detailTables.length > 0 || mainTableObj.fields.length > 0) {
                    this.mainTables.push(mainTableObj);
                }
            });

            let detailSize = 0;
            let fieldSize = 0;
            this.mainTables.forEach(d => {
                detailSize += d.detailTables.length;
                fieldSize += d.fields.length;
                d.detailTables.forEach(dt => {
                    fieldSize += dt.fields.length;
                });
            });

            Modal.confirm({
                content: `${getLabel('502904','识别到') +this.mainTables.length+getLabel('502905','个主表,')}${detailSize+getLabel('502906','个明细表，共计')+fieldSize+getLabel('502907','个字段，请确认是否应用识别的字段')}`,
                onCancel: () => {
                    this.clearFields();
                },
                onOk: () => {
                    this.workbook.suspendPaint();
                    this.mainTables.forEach((mainTable, tableIndex) => {
                        const sheet = this.workbook.getSheetFromName(mainTable.sheetName);
                        if (sheet) {
                            mainTable.fields.forEach((field, index) => {
                                const fieldCellType = new QuickTableFieldCellType(this, `mainTables[${tableIndex}].fields[${index}]`);
                                sheet.getCell(field.row, field.col)
                                    .textIndent(2.5)
                                    .backgroundImageLayout(GC.Spread.Sheets.ImageLayout.none)
                                    .backgroundImage(fieldCellType.backgroundImage)
                                    .cellType(fieldCellType);
                            });
                            mainTable.detailTables.forEach((detailTable, detailIndex) => {
                                detailTable.fields.forEach((detailField, detailFieldIndex) => {
                                    const fieldCellType = new QuickTableFieldCellType(this, `mainTables[${tableIndex}].detailTables[${detailIndex}].fields[${detailFieldIndex}]`);
                                    sheet.getCell(detailField.row, detailField.col)
                                        .textIndent(2.5)
                                        .backgroundImageLayout(GC.Spread.Sheets.ImageLayout.none)
                                        .backgroundImage(fieldCellType.backgroundImage)
                                        .cellType(fieldCellType);
                                });
                            });

                        }
                    });
                    this.workbook.resumePaint();
                    this.loading = false;
                },
                title: getLabel('502903','信息确认'),
            });
        }


        if (this.mainTables.length > 0) {
            Modal.confirm({
                content: getLabel('502902','字段识别将清除所有字段，请确认是否继续'),
                onOk: action,
                title: getLabel('502903','信息确认')
            })
        } else {
            action();
        }
    }

    isInDetails = (mainTable, row, col) => {
        let bool = false;
        mainTable.detailTables.forEach(area => {
            if (row >= area.row && row < area.row + area.rowCount && col >= area.col && col < area.col + area.colCount) {
                bool = true;
            }
        });

        return bool;
    }
    clearFields = () => {
        this.mainTables = [];
        this.detailIndex = {};
        this.fieldIndex = {};
        this.fieldName = {};
        this.loading = false;
    }
}